home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src-glu / nurbssrf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  36.3 KB  |  1,376 lines

  1. /* $Id: nurbssrf.c,v 1.2 1996/09/27 23:13:02 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.0
  6.  * Copyright (C) 1995-1996  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: nurbssrf.c,v $
  26.  * Revision 1.2  1996/09/27 23:13:02  brianp
  27.  * added return 0 to get_surface_dim() to silence warning
  28.  *
  29.  * Revision 1.1  1996/09/27 01:19:39  brianp
  30.  * Initial revision
  31.  *
  32.  */
  33.  
  34.  
  35. /*
  36.  * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
  37.  * See README2 for more info.
  38.  */
  39.  
  40.  
  41. #include <math.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <string.h> /* prototype of memcpy() */
  45. #include "nurbs.h"
  46.  
  47.  
  48. static int
  49. get_surface_dim(GLenum type)
  50. {
  51.     switch(type)
  52.     {
  53.         case GL_MAP2_VERTEX_3:            return 3;
  54.         case GL_MAP2_VERTEX_4:            return 4;
  55.         case GL_MAP2_INDEX:                return 1;
  56.         case GL_MAP2_COLOR_4:            return 4;
  57.         case GL_MAP2_NORMAL:            return 3;
  58.         case GL_MAP2_TEXTURE_COORD_1:    return 1;
  59.         case GL_MAP2_TEXTURE_COORD_2:    return 2;
  60.         case GL_MAP2_TEXTURE_COORD_3:    return 3;
  61.         case GL_MAP2_TEXTURE_COORD_4:    return 4;
  62.                 default:  abort();  /* TODO: is this OK? */
  63.     }
  64.         return 0; /*never get here*/
  65. }
  66.  
  67. static GLenum
  68. test_nurbs_surface(GLUnurbsObj *nobj, surface_attribs *attrib)
  69. {
  70.     GLenum err;
  71.     GLint tmp_int;
  72.  
  73.     if(attrib->sorder < 0 || attrib->torder < 0)
  74.     {
  75.         call_user_error(nobj,GLU_INVALID_VALUE);
  76.         return GLU_ERROR;
  77.     }
  78.     glGetIntegerv(GL_MAX_EVAL_ORDER,&tmp_int);
  79.     if(attrib->sorder > tmp_int || attrib->sorder < 2)
  80.     {
  81.         call_user_error(nobj,GLU_NURBS_ERROR1);
  82.         return GLU_ERROR;
  83.     }
  84.     if(attrib->torder > tmp_int || attrib->torder < 2)
  85.     {
  86.         call_user_error(nobj,GLU_NURBS_ERROR1);
  87.         return GLU_ERROR;
  88.     }
  89.     if(attrib->sknot_count < attrib->sorder +2)
  90.     {
  91.         call_user_error(nobj,GLU_NURBS_ERROR2);
  92.         return GLU_ERROR;
  93.     }
  94.     if(attrib->tknot_count < attrib->torder +2)
  95.     {
  96.         call_user_error(nobj,GLU_NURBS_ERROR2);
  97.         return GLU_ERROR;
  98.     }
  99.     if(attrib->s_stride < 0 || attrib->t_stride < 0)
  100.     {
  101.         call_user_error(nobj,GLU_NURBS_ERROR34);
  102.         return GLU_ERROR;
  103.     }
  104.     if(attrib->sknot==NULL || attrib->tknot==NULL || attrib->ctrlarray==NULL)
  105.     {
  106.         call_user_error(nobj,GLU_NURBS_ERROR36);
  107.         return GLU_ERROR;
  108.     }
  109.     if((err=test_knot(attrib->tknot_count,attrib->tknot,attrib->torder))
  110.         !=GLU_NO_ERROR)
  111.     {
  112.         call_user_error(nobj,err);
  113.         return GLU_ERROR;
  114.     }
  115.     if((err=test_knot(attrib->sknot_count,attrib->sknot,attrib->sorder))
  116.         !=GLU_NO_ERROR)
  117.     {
  118.         call_user_error(nobj,err);
  119.         return GLU_ERROR;
  120.     }
  121.     return GLU_NO_ERROR;
  122. }
  123.  
  124. static GLenum
  125. test_nurbs_surfaces(GLUnurbsObj *nobj)
  126. {
  127.     /* test the geometric data */
  128.     if(test_nurbs_surface(nobj,&(nobj->surface.geom))!=GLU_NO_ERROR)
  129.         return GLU_ERROR;
  130.     /* now test the attributive data */
  131.     /* color */
  132.     if(nobj->surface.color.type!=GLU_INVALID_ENUM)
  133.         if(test_nurbs_surface(nobj,&(nobj->surface.color))!=GLU_NO_ERROR)
  134.             return GLU_ERROR;
  135.     /* normal */
  136.     if(nobj->surface.normal.type!=GLU_INVALID_ENUM)
  137.         if(test_nurbs_surface(nobj,&(nobj->surface.normal))!=GLU_NO_ERROR)
  138.             return GLU_ERROR;
  139.     /* texture */
  140.     if(nobj->surface.texture.type!=GLU_INVALID_ENUM)
  141.         if(test_nurbs_surface(nobj,&(nobj->surface.texture))!=GLU_NO_ERROR)
  142.             return GLU_ERROR;
  143.     return GLU_NO_ERROR;
  144. }
  145.  
  146. static GLenum
  147. convert_surf(knot_str_type *s_knot, knot_str_type *t_knot,
  148.     surface_attribs *attrib, GLfloat **new_ctrl,
  149.     GLint *s_n_ctrl, GLint *t_n_ctrl)
  150. {
  151.     GLfloat **tmp_ctrl;
  152.     GLfloat *ctrl_offset;
  153.     GLint tmp_n_control;
  154.     GLint i,j,t_cnt,s_cnt;
  155.     GLint tmp_stride;
  156.     GLint dim;
  157.     GLenum err;
  158.  
  159.     /* valid range is empty? */
  160.     if((s_knot->unified_knot !=NULL && s_knot->unified_nknots==0) || 
  161.         (t_knot->unified_knot !=NULL && t_knot->unified_nknots==0))
  162.     {
  163.         if(s_knot->unified_knot)
  164.         {
  165.             free(s_knot->unified_knot);
  166.             s_knot->unified_knot=NULL;
  167.         }
  168.         if(t_knot->unified_knot)
  169.         {
  170.             free(t_knot->unified_knot);
  171.             t_knot->unified_knot=NULL;
  172.         }
  173.         *s_n_ctrl=0;
  174.         *t_n_ctrl=0;
  175.         return GLU_NO_ERROR;
  176.     }
  177.     t_cnt=attrib->tknot_count-attrib->torder;
  178.     s_cnt=attrib->sknot_count-attrib->sorder;
  179.     if((tmp_ctrl=(GLfloat **)malloc(sizeof(GLfloat *)*t_cnt))==NULL)
  180.         return GLU_OUT_OF_MEMORY;
  181.     if((err=explode_knot(s_knot))!=GLU_NO_ERROR)
  182.     {
  183.         free(tmp_ctrl);
  184.         if(s_knot->unified_knot)
  185.         {
  186.             free(s_knot->unified_knot);
  187.             s_knot->unified_knot=NULL;
  188.         }
  189.         return err;
  190.     }
  191.     if(s_knot->unified_knot)
  192.     {
  193.         free(s_knot->unified_knot);
  194.         s_knot->unified_knot=NULL;
  195.     }
  196.     if((err=calc_alphas(s_knot))!=GLU_NO_ERROR)
  197.     {
  198.         free(tmp_ctrl);
  199.         free(s_knot->new_knot);
  200.         return err;
  201.     }
  202.     free(s_knot->new_knot);
  203.     ctrl_offset=attrib->ctrlarray;
  204.     dim=attrib->dim;
  205.     for(i=0;i<t_cnt;i++)
  206.     {
  207.         if((err=calc_new_ctrl_pts(ctrl_offset,attrib->s_stride,s_knot,
  208.             dim,&(tmp_ctrl[i]),&tmp_n_control))!=GLU_NO_ERROR)
  209.         {
  210.             for(--i;i<=0;i--)
  211.                 free(tmp_ctrl[i]);
  212.             free(tmp_ctrl);
  213.             free(s_knot->alpha);
  214.             return err;
  215.         }
  216.         ctrl_offset+=attrib->t_stride;
  217.     }
  218.     free(s_knot->alpha);
  219.     tmp_stride=dim*tmp_n_control;
  220.     if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*tmp_stride*t_cnt))
  221.         ==NULL)
  222.     {
  223.         for(i=0;i<t_cnt;i++)
  224.             free(tmp_ctrl[i]);
  225.         free(tmp_ctrl);
  226.         return GLU_OUT_OF_MEMORY;
  227.     }
  228.     for(i=0;i<tmp_n_control;i++)
  229.         for(j=0;j<t_cnt;j++)
  230.             MEMCPY(*new_ctrl+j*dim+i*dim*t_cnt,tmp_ctrl[j]+dim*i,
  231.                 sizeof(GLfloat)*dim);
  232.     for(i=0;i<t_cnt;i++)
  233.         free(tmp_ctrl[i]);
  234.     free(tmp_ctrl);
  235.     *s_n_ctrl=tmp_n_control;
  236.     
  237.     if((tmp_ctrl=(GLfloat **)malloc(sizeof(GLfloat *)*(*s_n_ctrl)))==NULL)
  238.     {
  239.         return GLU_OUT_OF_MEMORY;
  240.     }
  241.     if((err=explode_knot(t_knot))!=GLU_NO_ERROR)
  242.     {
  243.         free(tmp_ctrl);
  244.         if(t_knot->unified_knot)
  245.         {
  246.             free(t_knot->unified_knot);
  247.             t_knot->unified_knot=NULL;
  248.         }
  249.         return err;
  250.     }
  251.     if(t_knot->unified_knot)
  252.     {
  253.         free(t_knot->unified_knot);
  254.         t_knot->unified_knot=NULL;
  255.     }
  256.     if((err=calc_alphas(t_knot))!=GLU_NO_ERROR)
  257.     {
  258.         free(tmp_ctrl);
  259.         free(t_knot->new_knot);
  260.         return err;
  261.     }
  262.     free(t_knot->new_knot);
  263.     ctrl_offset=*new_ctrl;
  264.     for(i=0;i<(*s_n_ctrl);i++)
  265.     {
  266.         if((err=calc_new_ctrl_pts(ctrl_offset,dim,t_knot,
  267.             dim,&(tmp_ctrl[i]),&tmp_n_control))!=GLU_NO_ERROR)
  268.         {
  269.             for(--i;i<=0;i--)
  270.                 free(tmp_ctrl[i]);
  271.             free(tmp_ctrl);
  272.             free(t_knot->alpha);
  273.             return err;
  274.         }
  275.         ctrl_offset+=dim*t_cnt;
  276.     }
  277.     free(t_knot->alpha);
  278.     free(*new_ctrl);
  279.     tmp_stride=dim*tmp_n_control;
  280.     if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*tmp_stride*(*s_n_ctrl)))
  281.         ==NULL)
  282.     {
  283.         for(i=0;i<(*s_n_ctrl);i++)
  284.             free(tmp_ctrl[i]);
  285.         free(tmp_ctrl);
  286.         return GLU_OUT_OF_MEMORY;
  287.     }
  288.     for(i=0;i<(*s_n_ctrl);i++)
  289.     {
  290.         MEMCPY(*new_ctrl+i*tmp_stride,tmp_ctrl[i],sizeof(GLfloat)*tmp_stride);
  291.         free(tmp_ctrl[i]);
  292.     }
  293.     free(tmp_ctrl);
  294.     *t_n_ctrl=tmp_n_control;
  295.     return GLU_NO_ERROR;
  296. }
  297.  
  298. /* prepare the knot information structures */
  299. static GLenum
  300. fill_knot_structures(GLUnurbsObj *nobj,
  301.     knot_str_type *geom_s_knot, knot_str_type *geom_t_knot,
  302.     knot_str_type *color_s_knot, knot_str_type *color_t_knot,
  303.     knot_str_type *normal_s_knot,  knot_str_type *normal_t_knot,
  304.     knot_str_type *texture_s_knot, knot_str_type *texture_t_knot)
  305. {
  306.     GLint order;
  307.     GLfloat *knot;
  308.     GLint nknots;
  309.     GLint t_min,t_max;
  310.  
  311.     geom_s_knot->unified_knot=NULL;
  312.     knot=geom_s_knot->knot=nobj->surface.geom.sknot;
  313.     nknots=geom_s_knot->nknots=nobj->surface.geom.sknot_count;
  314.     order=geom_s_knot->order=nobj->surface.geom.sorder;
  315.     geom_s_knot->delta_nknots=0;
  316.     t_min=geom_s_knot->t_min=order-1;
  317.     t_max=geom_s_knot->t_max=nknots-order;
  318.     if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  319.     {
  320.         call_user_error(nobj,GLU_NURBS_ERROR3);
  321.         return GLU_ERROR;
  322.     }
  323.     if(fabs(knot[0]-knot[t_min])<EPSILON)
  324.     {
  325.         /* knot open at beggining */
  326.         geom_s_knot->open_at_begin=GL_TRUE;
  327.     }
  328.     else
  329.         geom_s_knot->open_at_begin=GL_FALSE;
  330.     if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  331.     {
  332.         /* knot open at end */
  333.         geom_s_knot->open_at_end=GL_TRUE;
  334.     }
  335.     else
  336.         geom_s_knot->open_at_end=GL_FALSE;
  337.     geom_t_knot->unified_knot=NULL;
  338.     knot=geom_t_knot->knot=nobj->surface.geom.tknot;
  339.     nknots=geom_t_knot->nknots=nobj->surface.geom.tknot_count;
  340.     order=geom_t_knot->order=nobj->surface.geom.torder;
  341.     geom_t_knot->delta_nknots=0;
  342.     t_min=geom_t_knot->t_min=order-1;
  343.     t_max=geom_t_knot->t_max=nknots-order;
  344.     if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  345.     {
  346.         call_user_error(nobj,GLU_NURBS_ERROR3);
  347.         return GLU_ERROR;
  348.     }
  349.     if(fabs(knot[0]-knot[t_min])<EPSILON)
  350.     {
  351.         /* knot open at beggining */
  352.         geom_t_knot->open_at_begin=GL_TRUE;
  353.     }
  354.     else
  355.         geom_t_knot->open_at_begin=GL_FALSE;
  356.     if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  357.     {
  358.         /* knot open at end */
  359.         geom_t_knot->open_at_end=GL_TRUE;
  360.     }
  361.     else
  362.         geom_t_knot->open_at_end=GL_FALSE;
  363.  
  364.     if(nobj->surface.color.type!=GLU_INVALID_ENUM)
  365.     {
  366.         color_s_knot->unified_knot=(GLfloat *)1;
  367.         knot=color_s_knot->knot=nobj->surface.color.sknot;
  368.         nknots=color_s_knot->nknots=nobj->surface.color.sknot_count;
  369.         order=color_s_knot->order=nobj->surface.color.sorder;
  370.         color_s_knot->delta_nknots=0;
  371.         t_min=color_s_knot->t_min=order-1;
  372.         t_max=color_s_knot->t_max=nknots-order;
  373.         if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  374.         {
  375.             call_user_error(nobj,GLU_NURBS_ERROR3);
  376.             return GLU_ERROR;
  377.         }
  378.         if(fabs(knot[0]-knot[t_min])<EPSILON)
  379.         {
  380.             /* knot open at beggining */
  381.             color_s_knot->open_at_begin=GL_TRUE;
  382.         }
  383.         else
  384.             color_s_knot->open_at_begin=GL_FALSE;
  385.         if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  386.         {
  387.             /* knot open at end */
  388.             color_s_knot->open_at_end=GL_TRUE;
  389.         }
  390.         else
  391.             color_s_knot->open_at_end=GL_FALSE;
  392.         color_t_knot->unified_knot=(GLfloat *)1;
  393.         knot=color_t_knot->knot=nobj->surface.color.tknot;
  394.         nknots=color_t_knot->nknots=nobj->surface.color.tknot_count;
  395.         order=color_t_knot->order=nobj->surface.color.torder;
  396.         color_t_knot->delta_nknots=0;
  397.         t_min=color_t_knot->t_min=order-1;
  398.         t_max=color_t_knot->t_max=nknots-order;
  399.         if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  400.         {
  401.             call_user_error(nobj,GLU_NURBS_ERROR3);
  402.             return GLU_ERROR;
  403.         }
  404.         if(fabs(knot[0]-knot[t_min])<EPSILON)
  405.         {
  406.             /* knot open at beggining */
  407.             color_t_knot->open_at_begin=GL_TRUE;
  408.         }
  409.         else
  410.             color_t_knot->open_at_begin=GL_FALSE;
  411.         if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  412.         {
  413.             /* knot open at end */
  414.             color_t_knot->open_at_end=GL_TRUE;
  415.         }
  416.         else
  417.             color_t_knot->open_at_end=GL_FALSE;
  418.     }
  419.     else
  420.     {
  421.         color_s_knot->unified_knot=NULL;
  422.         color_t_knot->unified_knot=NULL;
  423.     }
  424.  
  425.     if(nobj->surface.normal.type!=GLU_INVALID_ENUM)
  426.     {
  427.         normal_s_knot->unified_knot=(GLfloat *)1;
  428.         knot=normal_s_knot->knot=nobj->surface.normal.sknot;
  429.         nknots=normal_s_knot->nknots=nobj->surface.normal.sknot_count;
  430.         order=normal_s_knot->order=nobj->surface.normal.sorder;
  431.         normal_s_knot->delta_nknots=0;
  432.         t_min=normal_s_knot->t_min=order-1;
  433.         t_max=normal_s_knot->t_max=nknots-order;
  434.         if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  435.         {
  436.             call_user_error(nobj,GLU_NURBS_ERROR3);
  437.             return GLU_ERROR;
  438.         }
  439.         if(fabs(knot[0]-knot[t_min])<EPSILON)
  440.         {
  441.             /* knot open at beggining */
  442.             normal_s_knot->open_at_begin=GL_TRUE;
  443.         }
  444.         else
  445.             normal_s_knot->open_at_begin=GL_FALSE;
  446.         if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  447.         {
  448.             /* knot open at end */
  449.             normal_s_knot->open_at_end=GL_TRUE;
  450.         }
  451.         else
  452.             normal_s_knot->open_at_end=GL_FALSE;
  453.         normal_t_knot->unified_knot=(GLfloat *)1;
  454.         knot=normal_t_knot->knot=nobj->surface.normal.tknot;
  455.         nknots=normal_t_knot->nknots=nobj->surface.normal.tknot_count;
  456.         order=normal_t_knot->order=nobj->surface.normal.torder;
  457.         normal_t_knot->delta_nknots=0;
  458.         t_min=normal_t_knot->t_min=order-1;
  459.         t_max=normal_t_knot->t_max=nknots-order;
  460.         if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  461.         {
  462.             call_user_error(nobj,GLU_NURBS_ERROR3);
  463.             return GLU_ERROR;
  464.         }
  465.         if(fabs(knot[0]-knot[t_min])<EPSILON)
  466.         {
  467.             /* knot open at beggining */
  468.             normal_t_knot->open_at_begin=GL_TRUE;
  469.         }
  470.         else
  471.             normal_t_knot->open_at_begin=GL_FALSE;
  472.         if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  473.         {
  474.             /* knot open at end */
  475.             normal_t_knot->open_at_end=GL_TRUE;
  476.         }
  477.         else
  478.             normal_t_knot->open_at_end=GL_FALSE;
  479.     }
  480.     else
  481.     {
  482.         normal_s_knot->unified_knot=NULL;
  483.         normal_t_knot->unified_knot=NULL;
  484.     }
  485.  
  486.     if(nobj->surface.texture.type!=GLU_INVALID_ENUM)
  487.     {
  488.         texture_s_knot->unified_knot=(GLfloat *)1;
  489.         knot=texture_s_knot->knot=nobj->surface.texture.sknot;
  490.         nknots=texture_s_knot->nknots=nobj->surface.texture.sknot_count;
  491.         order=texture_s_knot->order=nobj->surface.texture.sorder;
  492.         texture_s_knot->delta_nknots=0;
  493.         t_min=texture_s_knot->t_min=order-1;
  494.         t_max=texture_s_knot->t_max=nknots-order;
  495.         if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  496.         {
  497.             call_user_error(nobj,GLU_NURBS_ERROR3);
  498.             return GLU_ERROR;
  499.         }
  500.         if(fabs(knot[0]-knot[t_min])<EPSILON)
  501.         {
  502.             /* knot open at beggining */
  503.             texture_s_knot->open_at_begin=GL_TRUE;
  504.         }
  505.         else
  506.             texture_s_knot->open_at_begin=GL_FALSE;
  507.         if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  508.         {
  509.             /* knot open at end */
  510.             texture_s_knot->open_at_end=GL_TRUE;
  511.         }
  512.         else
  513.             texture_s_knot->open_at_end=GL_FALSE;
  514.         texture_t_knot->unified_knot=(GLfloat *)1;
  515.         knot=texture_t_knot->knot=nobj->surface.texture.tknot;
  516.         nknots=texture_t_knot->nknots=nobj->surface.texture.tknot_count;
  517.         order=texture_t_knot->order=nobj->surface.texture.torder;
  518.         texture_t_knot->delta_nknots=0;
  519.         t_min=texture_t_knot->t_min=order-1;
  520.         t_max=texture_t_knot->t_max=nknots-order;
  521.         if(fabs(knot[t_min]-knot[t_max])<EPSILON)
  522.         {
  523.             call_user_error(nobj,GLU_NURBS_ERROR3);
  524.             return GLU_ERROR;
  525.         }
  526.         if(fabs(knot[0]-knot[t_min])<EPSILON)
  527.         {
  528.             /* knot open at beggining */
  529.             texture_t_knot->open_at_begin=GL_TRUE;
  530.         }
  531.         else
  532.             texture_t_knot->open_at_begin=GL_FALSE;
  533.         if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
  534.         {
  535.             /* knot open at end */
  536.             texture_t_knot->open_at_end=GL_TRUE;
  537.         }
  538.         else
  539.             texture_t_knot->open_at_end=GL_FALSE;
  540.     }
  541.     else
  542.     {
  543.         texture_s_knot->unified_knot=NULL;
  544.         texture_t_knot->unified_knot=NULL;
  545.     }
  546.     return GLU_NO_ERROR;
  547. }
  548.  
  549. void
  550. free_new_ctrl(new_ctrl_type *p)
  551. {
  552.     if(p->geom_ctrl)
  553.         free(p->geom_ctrl);
  554.     if(p->geom_offsets)
  555.         free(p->geom_offsets);
  556.     if(p->color_ctrl)
  557.     {
  558.         free(p->color_ctrl);
  559.         if(p->color_offsets)
  560.             free(p->color_offsets);
  561.     }
  562.     if(p->normal_ctrl)
  563.     {
  564.         free(p->normal_ctrl);
  565.         if(p->normal_offsets)
  566.             free(p->normal_offsets);
  567.     }
  568.     if(p->texture_ctrl)
  569.     {
  570.         free(p->texture_ctrl);
  571.         if(p->texture_offsets)
  572.             free(p->texture_offsets);
  573.     }
  574. }
  575.  
  576. /* convert surfaces - geometry and possible attribute ones into equivalent */
  577. /* sequence of adjacent Bezier patches */
  578. static GLenum
  579. convert_surfs(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl)
  580. {
  581.     knot_str_type    geom_s_knot,color_s_knot,normal_s_knot,texture_s_knot;
  582.     knot_str_type    geom_t_knot,color_t_knot,normal_t_knot,texture_t_knot;
  583.     GLenum            err;
  584.  
  585.     if((err=fill_knot_structures(nobj,&geom_s_knot,&geom_t_knot,
  586.         &color_s_knot,&color_t_knot,&normal_s_knot,&normal_t_knot,
  587.         &texture_s_knot,&texture_t_knot)) !=GLU_NO_ERROR)
  588.     {
  589.         return err;
  590.     }
  591.     /* unify knots - all knots should have the same working range */
  592.     if((err=select_knot_working_range(nobj,&geom_s_knot,&color_s_knot,
  593.         &normal_s_knot,&texture_s_knot)) !=GLU_NO_ERROR)
  594.     {
  595.         call_user_error(nobj,err);
  596.         return err;
  597.     }
  598.     if((err=select_knot_working_range(nobj,&geom_t_knot,&color_t_knot,
  599.         &normal_t_knot,&texture_t_knot)) !=GLU_NO_ERROR)
  600.     {
  601.         free_unified_knots(&geom_s_knot,&color_s_knot,&normal_s_knot,
  602.             &texture_s_knot);
  603.         call_user_error(nobj,err);
  604.         return err;
  605.     }
  606.  
  607.     /* convert the geometry surface */
  608.     nobj->surface.geom.dim=get_surface_dim(nobj->surface.geom.type);
  609.     if((err=convert_surf(&geom_s_knot,&geom_t_knot,&(nobj->surface.geom),
  610.         &(new_ctrl->geom_ctrl),&(new_ctrl->geom_s_pt_cnt),
  611.         &(new_ctrl->geom_t_pt_cnt)))!=GLU_NO_ERROR)
  612.     {
  613.         free_unified_knots(&geom_s_knot,&color_s_knot,&normal_s_knot,
  614.             &texture_s_knot);
  615.         free_unified_knots(&geom_t_knot,&color_t_knot,&normal_t_knot,
  616.             &texture_t_knot);
  617.         call_user_error(nobj,err);
  618.         return err;
  619.     }
  620.     /* if additional attributive surfaces are given convert them as well */
  621.     if(color_s_knot.unified_knot)
  622.     {
  623.         nobj->surface.color.dim=get_surface_dim(nobj->surface.color.type);
  624.         if((err=convert_surf(&color_s_knot,&color_t_knot,&(nobj->surface.color),
  625.             &(new_ctrl->color_ctrl),&(new_ctrl->color_s_pt_cnt),
  626.             &(new_ctrl->color_t_pt_cnt)))!=GLU_NO_ERROR)
  627.         {
  628.             free_unified_knots(&color_s_knot,&color_s_knot,&normal_s_knot,
  629.                 &texture_s_knot);
  630.             free_unified_knots(&color_t_knot,&color_t_knot,&normal_t_knot,
  631.                 &texture_t_knot);
  632.             free_new_ctrl(new_ctrl);
  633.             call_user_error(nobj,err);
  634.             return err;
  635.         }
  636.     }
  637.     if(normal_s_knot.unified_knot)
  638.     {
  639.         nobj->surface.normal.dim=get_surface_dim(nobj->surface.normal.type);
  640.         if((err=convert_surf(&normal_s_knot,&normal_t_knot,
  641.             &(nobj->surface.normal),
  642.             &(new_ctrl->normal_ctrl),&(new_ctrl->normal_s_pt_cnt),
  643.             &(new_ctrl->normal_t_pt_cnt)))!=GLU_NO_ERROR)
  644.         {
  645.             free_unified_knots(&normal_s_knot,&normal_s_knot,&normal_s_knot,
  646.                 &texture_s_knot);
  647.             free_unified_knots(&normal_t_knot,&normal_t_knot,&normal_t_knot,
  648.                 &texture_t_knot);
  649.             free_new_ctrl(new_ctrl);
  650.             call_user_error(nobj,err);
  651.             return err;
  652.         }
  653.     }
  654.     if(texture_s_knot.unified_knot)
  655.     {
  656.         nobj->surface.texture.dim=get_surface_dim(nobj->surface.texture.type);
  657.         if((err=convert_surf(&texture_s_knot,&texture_t_knot,
  658.             &(nobj->surface.texture),
  659.             &(new_ctrl->texture_ctrl),&(new_ctrl->texture_s_pt_cnt),
  660.             &(new_ctrl->texture_t_pt_cnt)))!=GLU_NO_ERROR)
  661.         {
  662.             free_unified_knots(&texture_s_knot,&texture_s_knot,&texture_s_knot,
  663.                 &texture_s_knot);
  664.             free_unified_knots(&texture_t_knot,&texture_t_knot,&texture_t_knot,
  665.                 &texture_t_knot);
  666.             free_new_ctrl(new_ctrl);
  667.             call_user_error(nobj,err);
  668.             return err;
  669.         }
  670.     }
  671.     return GLU_NO_ERROR;
  672. }
  673.  
  674. /* tesselate the "boundary" Bezier edge strips */
  675. void
  676. tesselate_strip_t_line(GLint top_start,GLint top_end,GLint top_z,
  677.     GLint bottom_start,GLint bottom_end,GLint bottom_z,GLint bottom_domain)
  678. {
  679.     GLint top_cnt,bottom_cnt,tri_cnt,k;
  680.     GLint direction;
  681.  
  682.     top_cnt=top_end-top_start;
  683.     direction= (top_cnt>=0 ? 1: -1);
  684.     bottom_cnt=bottom_end-bottom_start;
  685.     glBegin(GL_LINES);
  686.     while(top_cnt)
  687.     {
  688.         if(bottom_cnt)
  689.             tri_cnt=top_cnt/bottom_cnt;
  690.         else
  691.             tri_cnt=abs(top_cnt);
  692.         for(k=0;k<=tri_cnt;k++ , top_start+=direction)
  693.         {
  694.             glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
  695.                 (GLfloat)bottom_start/bottom_domain);
  696.             glEvalPoint2(top_z,top_start);
  697.         }
  698.         if(bottom_cnt)
  699.         {
  700.             glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
  701.                 (GLfloat)bottom_start/bottom_domain);
  702.             bottom_start+=direction;
  703.             top_start-=direction;
  704.             glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
  705.                 (GLfloat)bottom_start/bottom_domain);
  706.             glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
  707.                 (GLfloat)bottom_start/bottom_domain);
  708.             glEvalPoint2(top_z,top_start);
  709.         }
  710.         top_cnt-=direction*tri_cnt;
  711.         bottom_cnt-=direction;
  712.     }
  713.     glEnd();
  714. }
  715.  
  716. void
  717. tesselate_strip_t_fill(GLint top_start,GLint top_end,GLint top_z,
  718.     GLint bottom_start,GLint bottom_end,GLint bottom_z,GLint bottom_domain)
  719. {
  720.     GLint top_cnt,bottom_cnt,tri_cnt,k;
  721.     GLint direction;
  722.  
  723.     top_cnt=top_end-top_start;
  724.     direction= (top_cnt>=0 ? 1: -1);
  725.     bottom_cnt=bottom_end-bottom_start;
  726.     while(top_cnt)
  727.     {
  728.         if(bottom_cnt)
  729.             tri_cnt=top_cnt/bottom_cnt;
  730.         else
  731.             tri_cnt=abs(top_cnt);
  732.         glBegin(GL_TRIANGLE_FAN);
  733.         glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
  734.             (GLfloat)bottom_start/bottom_domain);
  735.         for(k=0;k<=tri_cnt;k++ , top_start+=direction)
  736.             glEvalPoint2(top_z,top_start);
  737.         if(bottom_cnt)
  738.         {
  739.             bottom_start+=direction;
  740.             top_start-=direction;
  741.             glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
  742.                 (GLfloat)bottom_start/bottom_domain);
  743.         }
  744.         glEnd();
  745.         top_cnt-=direction*tri_cnt;
  746.         bottom_cnt-=direction;
  747.     }
  748. }
  749.  
  750. void
  751. tesselate_strip_t(GLenum display_mode, GLint top_start, GLint top_end, 
  752.     GLint top_z, GLint bottom_start, GLint bottom_end, GLint bottom_z, 
  753.     GLint bottom_domain)
  754. {
  755.     if(display_mode==GL_FILL)
  756.         tesselate_strip_t_fill(top_start,top_end,top_z,bottom_start,
  757.             bottom_end,bottom_z,bottom_domain);
  758.     else
  759.         tesselate_strip_t_line(top_start,top_end,top_z,bottom_start,
  760.             bottom_end,bottom_z,bottom_domain);
  761. }
  762.     
  763.  
  764. void
  765. tesselate_strip_s_fill(GLint top_start, GLint top_end, GLint top_z,
  766.     GLint bottom_start, GLint bottom_end, GLint bottom_z, GLfloat bottom_domain)
  767. {
  768.     GLint top_cnt,bottom_cnt,tri_cnt,k;
  769.     GLint direction;
  770.  
  771.     top_cnt=top_end-top_start;
  772.     direction= (top_cnt>=0 ? 1: -1);
  773.     bottom_cnt=bottom_end-bottom_start;
  774.     while(top_cnt)
  775.     {
  776.         if(bottom_cnt)
  777.             tri_cnt=top_cnt/bottom_cnt;
  778.         else
  779.             tri_cnt=abs(top_cnt);
  780.         glBegin(GL_TRIANGLE_FAN);
  781.         glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
  782.             (GLfloat)bottom_z/bottom_domain);
  783.         for(k=0;k<=tri_cnt;k++ , top_start+=direction)
  784.             glEvalPoint2(top_start,top_z);
  785.         if(bottom_cnt)
  786.         {
  787.             bottom_start+=direction;
  788.             top_start-=direction;
  789.             glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
  790.                 (GLfloat)bottom_z/bottom_domain);
  791.         }
  792.         glEnd();
  793.         top_cnt-=direction*tri_cnt;
  794.         bottom_cnt-=direction;
  795.     }
  796. }
  797.  
  798. void
  799. tesselate_strip_s_line(GLint top_start, GLint top_end, GLint top_z,
  800.     GLint bottom_start, GLint bottom_end, GLint bottom_z, GLfloat bottom_domain)
  801. {
  802.     GLint top_cnt,bottom_cnt,tri_cnt,k;
  803.     GLint direction;
  804.  
  805.     top_cnt=top_end-top_start;
  806.     direction= (top_cnt>=0 ? 1: -1);
  807.     bottom_cnt=bottom_end-bottom_start;
  808.     glBegin(GL_LINES);
  809.     while(top_cnt)
  810.     {
  811.         if(bottom_cnt)
  812.             tri_cnt=top_cnt/bottom_cnt;
  813.         else
  814.             tri_cnt=abs(top_cnt);
  815.         for(k=0;k<=tri_cnt;k++ , top_start+=direction)
  816.         {
  817.             glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
  818.                 (GLfloat)bottom_z/bottom_domain);
  819.             glEvalPoint2(top_start,top_z);
  820.         }
  821.         if(bottom_cnt)
  822.         {
  823.             glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
  824.                 (GLfloat)bottom_z/bottom_domain);
  825.             bottom_start+=direction;
  826.             top_start-=direction;
  827.             glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
  828.                 (GLfloat)bottom_z/bottom_domain);
  829.             glEvalPoint2(top_start,top_z);
  830.             glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
  831.                 (GLfloat)bottom_z/bottom_domain);
  832.         }
  833.         top_cnt-=direction*tri_cnt;
  834.         bottom_cnt-=direction;
  835.     }
  836.     glEnd();
  837. }
  838.  
  839. void
  840. tesselate_strip_s(GLenum display_mode, GLint top_start, GLint top_end,
  841.     GLint top_z, GLint bottom_start, GLint bottom_end, GLint bottom_z,
  842.     GLfloat bottom_domain)
  843. {
  844.     if(display_mode==GL_FILL)
  845.         tesselate_strip_s_fill(top_start,top_end,top_z,bottom_start,
  846.             bottom_end,bottom_z,bottom_domain);
  847.     else
  848.         tesselate_strip_s_line(top_start,top_end,top_z,bottom_start,
  849.             bottom_end,bottom_z,bottom_domain);
  850. }
  851.  
  852. void
  853. tesselate_bottom_left_corner(GLenum display_mode, GLfloat s_1, GLfloat t_1)
  854. {
  855.     if(display_mode==GL_FILL)
  856.     {
  857.         glBegin(GL_TRIANGLE_FAN);
  858.         glEvalPoint2(1,1);
  859.         glEvalCoord2f(s_1,0.0);
  860.         glEvalCoord2f(0.0,0.0);
  861.         glEvalCoord2f(0.0,t_1);
  862.     }
  863.     else
  864.     {
  865.         glBegin(GL_LINES);
  866.         glEvalCoord2f(0.0,0.0);
  867.         glEvalCoord2f(0.0,t_1);
  868.         glEvalCoord2f(0.0,0.0);
  869.         glEvalPoint2(1,1);
  870.         glEvalCoord2f(0.0,0.0);
  871.         glEvalCoord2f(s_1,0.0);
  872.     }
  873.     glEnd();
  874. }
  875.  
  876. void
  877. tesselate_bottom_right_corner(GLenum display_mode, GLint v_top,GLint v_bottom,
  878.     GLfloat s_1, GLfloat t_1)
  879. {
  880.     if(display_mode==GL_FILL)
  881.     {
  882.         glBegin(GL_TRIANGLE_FAN);
  883.         glEvalPoint2(1,v_top);
  884.         glEvalCoord2f(0.0,v_bottom*t_1);
  885.         glEvalCoord2f(0.0,(v_bottom+1)*t_1);
  886.         glEvalCoord2f(s_1,(v_bottom+1)*t_1);
  887.     }
  888.     else
  889.     {
  890.         glBegin(GL_LINES);
  891.         glEvalCoord2f(0.0,(v_bottom+1)*t_1);
  892.         glEvalPoint2(1,v_top);
  893.         glEvalCoord2f(0.0,(v_bottom+1)*t_1);
  894.         glEvalCoord2f(0.0,v_bottom*t_1);
  895.         glEvalCoord2f(0.0,(v_bottom+1)*t_1);
  896.         glEvalCoord2f(s_1,(v_bottom+1)*t_1);
  897.     }
  898.     glEnd();
  899. }
  900.  
  901. void
  902. tesselate_top_left_corner(GLenum display_mode, GLint u_right, GLint u_left,
  903.     GLfloat s_1, GLfloat t_1)
  904. {
  905.     if(display_mode==GL_FILL)
  906.     {
  907.         glBegin(GL_TRIANGLE_FAN);
  908.         glEvalPoint2(u_right,1);
  909.         glEvalCoord2f((u_left+1)*s_1,t_1);
  910.         glEvalCoord2f((u_left+1)*s_1,0.0);
  911.         glEvalCoord2f(u_left*s_1,0.0);
  912.     }
  913.     else
  914.     {
  915.         glBegin(GL_LINES);
  916.         glEvalCoord2f((u_left+1)*s_1,0.0);
  917.         glEvalPoint2(u_right,1);
  918.         glEvalCoord2f((u_left+1)*s_1,0.0);
  919.         glEvalCoord2f(u_left*s_1,0.0);
  920.         glEvalCoord2f((u_left+1)*s_1,0.0);
  921.         glEvalCoord2f((u_left+1)*s_1,t_1);
  922.     }
  923.     glEnd();
  924. }
  925.  
  926. void
  927. tesselate_top_right_corner(GLenum display_mode, GLint u_left, GLint v_bottom,
  928.     GLint u_right, GLint v_top, GLfloat s_1, GLfloat t_1)
  929. {
  930.     if(display_mode==GL_FILL)
  931.     {
  932.         glBegin(GL_TRIANGLE_FAN);
  933.         glEvalPoint2(u_left,v_bottom);
  934.         glEvalCoord2f((u_right-1)*s_1,v_top*t_1);
  935.         glEvalCoord2f(u_right*s_1,v_top*t_1);
  936.         glEvalCoord2f(u_right*s_1,(v_top-1)*t_1);
  937.     }
  938.     else
  939.     {
  940.         glBegin(GL_LINES);
  941.         glEvalCoord2f(u_right*s_1,v_top*t_1);
  942.         glEvalPoint2(u_left,v_bottom);
  943.         glEvalCoord2f(u_right*s_1,v_top*t_1);
  944.         glEvalCoord2f(u_right*s_1,(v_top-1)*t_1);
  945.         glEvalCoord2f(u_right*s_1,v_top*t_1);
  946.         glEvalCoord2f((u_right-1)*s_1,v_top*t_1);
  947.     }
  948.     glEnd();
  949. }
  950.  
  951. /* do mesh mapping of Bezier */
  952. static void
  953. nurbs_map_bezier(GLenum display_mode,GLint *sfactors,GLint *tfactors,
  954.     GLint s_bezier_cnt, GLint t_bezier_cnt, GLint s, GLint t)
  955. {
  956.     GLint        top,bottom,right,left;
  957.  
  958.  
  959.     if(s==0)
  960.     {
  961.         top=*(tfactors+t*3);
  962.         bottom=*(tfactors+t*3+1);
  963.     }
  964.     else
  965.     if(s==s_bezier_cnt-1)
  966.     {
  967.         top=*(tfactors+t*3+2);
  968.         bottom=*(tfactors+t*3);
  969.     }
  970.     else
  971.     {
  972.         top=bottom=*(tfactors+t*3);
  973.     }
  974.     if(t==0)
  975.     {
  976.         left=*(sfactors+s*3+1);
  977.         right=*(sfactors+s*3);
  978.     }
  979.     else
  980.     if(t==t_bezier_cnt-1)
  981.     {
  982.         left=*(sfactors+s*3);
  983.         right=*(sfactors+s*3+2);
  984.     }
  985.     else
  986.     {
  987.         left=right=*(sfactors+s*3);
  988.     }
  989.  
  990.     if(top>bottom)
  991.     {
  992.         if(left<right)
  993.         {
  994.             glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
  995.             glEvalMesh2(display_mode,1,right, 1, top);
  996.             tesselate_strip_s(display_mode,1,right,1,1,left,0,(GLfloat)left);
  997.             tesselate_bottom_left_corner(display_mode,(GLfloat)(1.0/left),
  998.                 (GLfloat)(1.0/bottom));
  999. /*            tesselate_strip_t(display_mode,1,top,1,1,bottom,0,(GLfloat)bottom);*/
  1000.             tesselate_strip_t(display_mode,top,1,1,bottom,1,0,(GLfloat)bottom);
  1001.         }
  1002.         else
  1003.         if(left==right)
  1004.         {
  1005.             glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
  1006.             glEvalMesh2(display_mode,1,right, 0, top);
  1007. /*            tesselate_strip_t(display_mode,0,top,1,0,bottom,0,(GLfloat)bottom);*/
  1008.             tesselate_strip_t(display_mode,top,0,1,bottom,0,0,(GLfloat)bottom);
  1009.         }
  1010.         else
  1011.         {
  1012.             glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
  1013.             glEvalMesh2(display_mode,1,left, 0, top-1);
  1014. /*            tesselate_strip_t(display_mode,0,top-1,1,0,bottom-1,0,
  1015.                 (GLfloat)bottom);*/
  1016.             tesselate_strip_t(display_mode,top-1,0,1,bottom-1,0,0,
  1017.                 (GLfloat)bottom);
  1018.             tesselate_bottom_right_corner(display_mode,top-1,bottom-1,
  1019.                 (GLfloat)(1.0/right),(GLfloat)(1.0/bottom));
  1020. /*            tesselate_strip_s(display_mode,1,left,top-1,1,right,right,
  1021.                 (GLfloat)right);*/
  1022.             tesselate_strip_s(display_mode,left,1,top-1,right,1,right,
  1023.                 (GLfloat)right);
  1024.         }
  1025.     }
  1026.     else
  1027.     if(top==bottom)
  1028.     {
  1029.         if(left<right)
  1030.         {
  1031.             glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
  1032.             glEvalMesh2(display_mode,0,right, 1, top);
  1033.             tesselate_strip_s(display_mode,0,right,1,0,left,0,(GLfloat)left);
  1034.         }
  1035.         else
  1036.         if(left==right)
  1037.         {
  1038.             glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
  1039.             glEvalMesh2(display_mode,0,right, 0, top);
  1040.         }
  1041.         else
  1042.         {
  1043.             glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
  1044.             glEvalMesh2(display_mode,0,left, 0, top-1);
  1045. /*            tesselate_strip_s(display_mode,0,left,top-1,0,right,right,
  1046.                 (GLfloat)right);*/
  1047.             tesselate_strip_s(display_mode,left,0,top-1,right,0,right,
  1048.                 (GLfloat)right);
  1049.         }
  1050.     }
  1051.     else
  1052.     {
  1053.         if(left<right)
  1054.         {
  1055.             glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
  1056.             glEvalMesh2(display_mode,0,right-1, 1, bottom);
  1057.             tesselate_strip_s(display_mode,0,right-1,1,0,left-1,0,
  1058.                 (GLfloat)left);
  1059.             tesselate_top_left_corner(display_mode,right-1,left-1,
  1060.                 (GLfloat)(1.0/left),(GLfloat)(1.0/top));
  1061.             tesselate_strip_t(display_mode,1,bottom,right-1,1,top,top,
  1062.                 (GLfloat)top);
  1063.         }
  1064.         else
  1065.         if(left==right)
  1066.         {
  1067.             glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
  1068.             glEvalMesh2(display_mode,0,right-1, 0, bottom);
  1069.             tesselate_strip_t(display_mode,0,bottom,right-1,0,top,top,
  1070.                 (GLfloat)top);
  1071.         }
  1072.         else
  1073.         {
  1074.             glMapGrid2f(left, 0.0, 1.0, bottom, 0.0, 1.0);
  1075.             glEvalMesh2(display_mode,0,left-1, 0, bottom-1);
  1076.             tesselate_strip_t(display_mode,0,bottom-1,left-1,0,top-1,top,
  1077.                 (GLfloat)top);
  1078.             tesselate_top_right_corner(display_mode,left-1,bottom-1,right,top,
  1079.                 (GLfloat)(1.0/right),(GLfloat)(1.0/top));
  1080. /*            tesselate_strip_s(display_mode,0,left-1,bottom-1,0,right-1,right,
  1081.                 (GLfloat)right);*/
  1082.             tesselate_strip_s(display_mode,left-1,0,bottom-1,right-1,0,right,
  1083.                 (GLfloat)right);
  1084.         }
  1085.     }
  1086. }
  1087.  
  1088. /* draw NURBS surface in OUTLINE POLYGON mode */
  1089. static void
  1090. draw_polygon_mode( GLenum display_mode, GLUnurbsObj *nobj,
  1091.     new_ctrl_type *new_ctrl, GLint *sfactors, GLint *tfactors )
  1092. {
  1093.     GLsizei                offset;
  1094.     GLint                t_bezier_cnt,s_bezier_cnt;
  1095.     GLboolean            do_color,do_normal,do_texture;
  1096.     GLint                i,j;
  1097.  
  1098.     t_bezier_cnt=new_ctrl->t_bezier_cnt;
  1099.     s_bezier_cnt=new_ctrl->s_bezier_cnt;
  1100.     glEnable(nobj->surface.geom.type);
  1101.     if(new_ctrl->color_ctrl)
  1102.     {
  1103.         glEnable(nobj->surface.color.type);
  1104.         do_color=GL_TRUE;
  1105.     }
  1106.     else
  1107.         do_color=GL_FALSE;
  1108.     if(new_ctrl->normal_ctrl)
  1109.     {
  1110.         glEnable(nobj->surface.normal.type);
  1111.         do_normal=GL_TRUE;
  1112.     }
  1113.     else
  1114.         do_normal=GL_FALSE;
  1115.     if(new_ctrl->texture_ctrl)
  1116.     {
  1117.         glEnable(nobj->surface.texture.type);
  1118.         do_texture=GL_TRUE;
  1119.     }
  1120.     else
  1121.         do_texture=GL_FALSE;
  1122.     for(j=0; j<s_bezier_cnt; j++)
  1123.     {
  1124.         for(i=0; i<t_bezier_cnt; i++)
  1125.         {
  1126.             offset=j*t_bezier_cnt + i;
  1127.             if(fine_culling_test_3D(nobj,*(new_ctrl->geom_offsets + offset),
  1128.                     nobj->surface.geom.sorder,nobj->surface.geom.torder,
  1129.                     new_ctrl->geom_s_stride,new_ctrl->geom_t_stride,
  1130.                     nobj->surface.geom.dim))
  1131.                 continue;
  1132.             glMap2f(nobj->surface.geom.type,0.0,1.0,new_ctrl->geom_s_stride,
  1133.                 nobj->surface.geom.sorder,0.0,1.0,new_ctrl->geom_t_stride,
  1134.                 nobj->surface.geom.torder,*(new_ctrl->geom_offsets + offset));
  1135.             if(do_color)
  1136.             {
  1137.                 glMap2f(nobj->surface.color.type,0.0,1.0,
  1138.                     new_ctrl->color_s_stride,nobj->surface.color.sorder,
  1139.                     0.0,1.0,new_ctrl->color_t_stride,nobj->surface.color.torder,
  1140.                     *(new_ctrl->color_offsets + offset));
  1141.             }
  1142.             if(do_normal)
  1143.             {
  1144.                 glMap2f(nobj->surface.normal.type,0.0,1.0,
  1145.                     new_ctrl->normal_s_stride,nobj->surface.normal.sorder,
  1146.                     0.0,1.0,new_ctrl->normal_t_stride,
  1147.                     nobj->surface.normal.torder,
  1148.                     *(new_ctrl->normal_offsets+offset));
  1149.             }
  1150.             if(do_texture)
  1151.             {
  1152.                 glMap2f(nobj->surface.texture.type,0.0,1.0,
  1153.                     new_ctrl->texture_s_stride,nobj->surface.texture.sorder,
  1154.                     0.0,1.0,new_ctrl->texture_t_stride,
  1155.                     nobj->surface.texture.torder,
  1156.                     *(new_ctrl->texture_offsets+offset));
  1157.             }
  1158. /*            glMapGrid2f(sfactors[j*3+0],0.0,1.0,tfactors[i*3+0],0.0,1.0);
  1159.             glEvalMesh2(display_mode,0,sfactors[j*3+0],0,tfactors[i*3+0]);*/
  1160.             nurbs_map_bezier(display_mode,sfactors,tfactors,s_bezier_cnt,
  1161.                 t_bezier_cnt,j,i);
  1162.         }
  1163.     }
  1164. }
  1165.  
  1166.  
  1167.  
  1168. /* draw NURBS surface in OUTLINE POLYGON mode */
  1169. #if 0
  1170. static void
  1171. draw_patch_mode( GLenum display_mode, GLUnurbsObj *nobj,
  1172.     new_ctrl_type *new_ctrl, GLint *sfactors, GLint *tfactors )
  1173. {
  1174.     GLsizei                offset;
  1175.     GLint                t_bezier_cnt,s_bezier_cnt;
  1176.     GLboolean            do_color,do_normal,do_texture;
  1177.     GLint                i,j;
  1178.  
  1179.     t_bezier_cnt=new_ctrl->t_bezier_cnt;
  1180.     s_bezier_cnt=new_ctrl->s_bezier_cnt;
  1181.     glEnable(nobj->surface.geom.type);
  1182.     if(new_ctrl->color_ctrl)
  1183.     {
  1184.         glEnable(nobj->surface.color.type);
  1185.         do_color=GL_TRUE;
  1186.     }
  1187.     else
  1188.         do_color=GL_FALSE;
  1189.     if(new_ctrl->normal_ctrl)
  1190.     {
  1191.         glEnable(nobj->surface.normal.type);
  1192.         do_normal=GL_TRUE;
  1193.     }
  1194.     else
  1195.         do_normal=GL_FALSE;
  1196.     if(new_ctrl->texture_ctrl)
  1197.     {
  1198.         glEnable(nobj->surface.texture.type);
  1199.         do_texture=GL_TRUE;
  1200.     }
  1201.     else
  1202.         do_texture=GL_FALSE;
  1203.     for(j=0; j<s_bezier_cnt; j++)
  1204.     {
  1205.         for(i=0; i<t_bezier_cnt; i++)
  1206.         {
  1207.             offset=j*t_bezier_cnt + i;
  1208.             if(fine_culling_test_3D(nobj,*(new_ctrl->geom_offsets + offset),
  1209.                     nobj->surface.geom.sorder,nobj->surface.geom.torder,
  1210.                     new_ctrl->geom_s_stride,new_ctrl->geom_t_stride,
  1211.                     nobj->surface.geom.dim))
  1212.                 continue;
  1213.             glMap2f(nobj->surface.geom.type,0.0,1.0,new_ctrl->geom_s_stride,
  1214.                 nobj->surface.geom.sorder,0.0,1.0,new_ctrl->geom_t_stride,
  1215.                 nobj->surface.geom.torder,*(new_ctrl->geom_offsets + offset));
  1216.             if(do_color)
  1217.             {
  1218.                 glMap2f(nobj->surface.color.type,0.0,1.0,
  1219.                     new_ctrl->color_s_stride,nobj->surface.color.sorder,
  1220.                     0.0,1.0,new_ctrl->color_t_stride,nobj->surface.color.torder,
  1221.                     *(new_ctrl->color_offsets + offset));
  1222.             }
  1223.             if(do_normal)
  1224.             {
  1225.                 glMap2f(nobj->surface.normal.type,0.0,1.0,
  1226.                     new_ctrl->normal_s_stride,nobj->surface.normal.sorder,
  1227.                     0.0,1.0,new_ctrl->normal_t_stride,
  1228.                     nobj->surface.normal.torder,
  1229.                     *(new_ctrl->normal_offsets+offset));
  1230.             }
  1231.             if(do_texture)
  1232.             {
  1233.                 glMap2f(nobj->surface.texture.type,0.0,1.0,
  1234.                     new_ctrl->texture_s_stride,nobj->surface.texture.sorder,
  1235.                     0.0,1.0,new_ctrl->texture_t_stride,
  1236.                     nobj->surface.texture.torder,
  1237.                     *(new_ctrl->texture_offsets+offset));
  1238.             }
  1239.             nurbs_map_bezier(display_mode,sfactors,tfactors,s_bezier_cnt,
  1240.                 t_bezier_cnt,i,j);
  1241. /*            glMapGrid2f(sfactors[j],0.0,1.0,tfactors[i],0.0,1.0);
  1242.             glEvalMesh2(display_mode,0,sfactors[j],0,tfactors[i]);*/
  1243.         }
  1244.     }
  1245. }
  1246. #endif
  1247.  
  1248.  
  1249.  
  1250. void
  1251. init_new_ctrl(new_ctrl_type *p)
  1252. {
  1253.     p->geom_ctrl=p->color_ctrl=p->normal_ctrl=p->texture_ctrl=NULL;
  1254.     p->geom_offsets=p->color_offsets=p->normal_offsets=p->texture_offsets=NULL;
  1255.     p->s_bezier_cnt=p->t_bezier_cnt=0;
  1256. }
  1257.  
  1258. GLenum
  1259. augment_new_ctrl(GLUnurbsObj *nobj, new_ctrl_type *p)
  1260. {
  1261.     GLsizei offset_size;
  1262.     GLint    i,j;
  1263.  
  1264.     p->s_bezier_cnt=(p->geom_s_pt_cnt)/(nobj->surface.geom.sorder);
  1265.     p->t_bezier_cnt=(p->geom_t_pt_cnt)/(nobj->surface.geom.torder);
  1266.     offset_size=(p->s_bezier_cnt)*(p->t_bezier_cnt);
  1267.     p->geom_t_stride=nobj->surface.geom.dim;
  1268.     p->geom_s_stride=(p->geom_t_pt_cnt)*(nobj->surface.geom.dim);
  1269.     p->color_t_stride=nobj->surface.color.dim;
  1270.     p->color_s_stride=(p->color_t_pt_cnt)*(nobj->surface.color.dim);
  1271.     p->normal_t_stride=nobj->surface.normal.dim;
  1272.     p->normal_s_stride=(p->normal_t_pt_cnt)*(nobj->surface.normal.dim);
  1273.     p->texture_t_stride=nobj->surface.texture.dim;
  1274.     p->texture_s_stride=(p->texture_t_pt_cnt)*(nobj->surface.texture.dim);
  1275.     if((p->geom_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
  1276.     {
  1277.         call_user_error(nobj,GLU_OUT_OF_MEMORY);
  1278.         return GLU_ERROR;
  1279.     }
  1280.     if(p->color_ctrl)
  1281.         if((p->color_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
  1282.         {
  1283.             free_new_ctrl(p);
  1284.             call_user_error(nobj,GLU_OUT_OF_MEMORY);
  1285.             return GLU_ERROR;
  1286.         }
  1287.     if(p->normal_ctrl)
  1288.         if((p->normal_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
  1289.         {
  1290.             free_new_ctrl(p);
  1291.             call_user_error(nobj,GLU_OUT_OF_MEMORY);
  1292.             return GLU_ERROR;
  1293.         }
  1294.     if(p->texture_ctrl)
  1295.         if((p->texture_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
  1296.         {
  1297.             free_new_ctrl(p);
  1298.             call_user_error(nobj,GLU_OUT_OF_MEMORY);
  1299.             return GLU_ERROR;
  1300.         }
  1301.     for(i=0;i<p->s_bezier_cnt;i++)
  1302.         for(j=0;j<p->t_bezier_cnt;j++)
  1303.             *(p->geom_offsets + i*(p->t_bezier_cnt) + j) =
  1304.                 p->geom_ctrl + i*(nobj->surface.geom.sorder)*
  1305.                 (nobj->surface.geom.dim)*(p->geom_t_pt_cnt) +
  1306.                 j*(nobj->surface.geom.dim)*(nobj->surface.geom.torder);
  1307.     if(p->color_ctrl)
  1308.         for(i=0;i<p->s_bezier_cnt;i++)
  1309.             for(j=0;j<p->t_bezier_cnt;j++)
  1310.                 *(p->color_offsets + i*(p->t_bezier_cnt) + j) =
  1311.                     p->color_ctrl + i*(nobj->surface.color.sorder)*
  1312.                     (nobj->surface.color.dim)*(p->color_t_pt_cnt) +
  1313.                     j*(nobj->surface.color.dim)*(nobj->surface.color.torder);
  1314.     if(p->normal_ctrl)
  1315.         for(i=0;i<p->s_bezier_cnt;i++)
  1316.             for(j=0;j<p->t_bezier_cnt;j++)
  1317.                 *(p->normal_offsets + i*(p->t_bezier_cnt) + j) =
  1318.                     p->normal_ctrl + i*(nobj->surface.normal.sorder)*
  1319.                     (nobj->surface.normal.dim)*(p->normal_t_pt_cnt) +
  1320.                     j*(nobj->surface.normal.dim)*(nobj->surface.normal.torder);
  1321.     if(p->texture_ctrl)
  1322.         for(i=0;i<p->s_bezier_cnt;i++)
  1323.             for(j=0;j<p->t_bezier_cnt;j++)
  1324.                 *(p->texture_offsets + i*(p->t_bezier_cnt) + j) =
  1325.                     p->texture_ctrl + i*(nobj->surface.texture.sorder)*
  1326.                     (nobj->surface.texture.dim)*(p->texture_t_pt_cnt) +
  1327.                     j*(nobj->surface.texture.dim)*(nobj->surface.texture.torder);
  1328.     return GLU_NO_ERROR;
  1329. }
  1330.  
  1331. /* main NURBS surface procedure */
  1332. void
  1333. do_nurbs_surface( GLUnurbsObj *nobj )
  1334. {
  1335.     GLint            *sfactors,*tfactors;
  1336.     new_ctrl_type    new_ctrl;
  1337.  
  1338.     /* test user supplied data */
  1339.     if(test_nurbs_surfaces(nobj)!=GLU_NO_ERROR)
  1340.         return;
  1341.  
  1342.     init_new_ctrl(&new_ctrl);
  1343.  
  1344.     if(convert_surfs(nobj,&new_ctrl)!=GLU_NO_ERROR)
  1345.         return;
  1346.     if(augment_new_ctrl(nobj,&new_ctrl)!=GLU_NO_ERROR)
  1347.         return;
  1348.     if(glu_do_sampling_3D(nobj,&new_ctrl,&sfactors,&tfactors)!=GLU_NO_ERROR)
  1349.     {
  1350.         free_new_ctrl(&new_ctrl);
  1351.         return;
  1352.     }
  1353.     switch(nobj->display_mode)
  1354.     {
  1355.         case GLU_FILL:
  1356. /*            if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
  1357.                 draw_polygon_mode(GL_FILL,nobj,&new_ctrl,sfactors,tfactors);
  1358.             break;
  1359.         case GLU_OUTLINE_POLYGON:
  1360.             /* TODO - missing trimming handeling */
  1361. /* just for now - no OUTLINE_PATCH mode 
  1362.             draw_patch_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
  1363.             break; */
  1364.         case GLU_OUTLINE_PATCH:
  1365. /*            if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
  1366.                 draw_polygon_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
  1367.             break;
  1368.         default:
  1369.             abort();  /* TODO: is this OK? */
  1370.     }
  1371.     free(sfactors);
  1372.     free(tfactors);
  1373.     free_new_ctrl(&new_ctrl);
  1374. }
  1375.  
  1376.